from functools import wraps
from webutils.datastructure import NameSpace

tasks = NameSpace()


def ignore(key):
    """每条广播消息都会包含一些任务的元信息，比如发送者身份
    发送者将消息广播后，可能会收到该信息，有些场景下发送者并不需要
    处理这些信息，所以需要将其忽略
    """
    assert key in ('same_user', 'same_session')

    def ignore_decorator(f):
        @wraps(f)
        async def wrapper(ws, task_args, task_meta):
            if key == 'same_user':
                if ws.session.user and \
                        ws.session.user.id == task_meta.get('session_user_id'):
                    ws.logger.debug('broadcast task %s ignored because of %s',
                                    wrapper.__name__, key)
                    return
            elif key == 'same_session':
                if ws.session.id == task_meta.get('session_id'):
                    ws.logger.debug('broadcast task %s ignored because of %s',
                                    wrapper.__name__, key)
                    return
            return await f(ws, task_args, task_meta)

        return wrapper

    return ignore_decorator


######
# 聊天
######
@tasks.register('broadcast_chat')
@ignore('same_session')
async def broadcast_chat(ws, task_args, task_meta):
    await ws.write_json_message(task_args)


@tasks.register('broadcast_chat_blacklist')
async def broadcast_chat_blacklist(ws, task_args, task_meta):
    await ws.write_json_message(task_args)


##########
# 单元状态
##########


@tasks.register('broadcast_state')
@ignore('same_session')
async def broadcast_state(ws, task_args, task_meta):
    await ws.write_json_message(task_args)


@tasks.register('broadcast_unit_state')
async def broadcast_unit_state(ws, task_args, task_meta):
    await ws.write_json_message(task_args)


##########
# 登录状态
##########
@tasks.register('broadcast_login')
@ignore('same_user')
async def broadcast_login(ws, task_args, task_meta):
    await ws.write_json_message(task_args)


@tasks.register(':q'
                '')
async def broadcast_logout(ws, task_args, task_meta):
    await ws.write_json_message(task_args)
    # if self_ws:??
    # if ws.session.user.id ==
    # ws.abort('offline act')


###########
# 发送消息
###########
@tasks.register('broadcast_counter')
async def broadcast_counter(ws, task_args, task_meta):
    await ws.write_json_message(task_args)
